{{! 反序列化方法：精确验证和错误处理 }}
deserialize(decoder: Decoder, plain: ESObject): {{class.className}}{{#if class.generics.isGeneric}}<{{genericParametersString class.generics.parameters}}>{{/if}} {
  {{! 类型验证 }}
  if (!TypeUtils.isObject(plain)) {
    TurboTransLogger.error('Cannot deserialize `{{class.className}}` from non-object serialized data in strict deserialization.')
    throw new SerializationError(
      SerializationErrorCodes.CANNOT_BEGIN_STRUCTURE_ON_NON_STRUCTURE_KIND,
      'Cannot deserialize `{{class.className}}` from non-object serialized data in strict deserialization.'
    );
  }

  {{! 属性状态跟踪变量 }}
  {{#each properties}}
    let {{analysis.name}}Seen = false;
    let {{analysis.name}}Value: {{serializer.decoderType}} = undefined;
  {{/each}}

  {{! Object.entries 遍历 }}
  const entries: [string, ESObject][] = Object.entries(plain);
  for (let i = 0; i < entries.length; i++) {
    const entry: [string, ESObject] = entries[i];
    const key = entry[0];
    const value: ESObject = entry[1];
    const elementIndex = decoder.decodeElementIndex(this.serialDescriptor, key, value);

    switch (elementIndex) {
      {{#each properties}}
      case {{@index}}:
        {{analysis.name}}Seen = true;
        {{#if analysis.decorators.isPlainValue}}
        {{analysis.name}}Value = value;
        {{else}}
        {{#if (and (eqPrimitiveType analysis.type.kind) (not (hasDecoratorWith analysis.decorators)))}}
        {{analysis.name}}Value = decoder.{{serializer.decodeMethod}}(value);
        {{else}}
        {{analysis.name}}Value = this.{{analysis.name}}Serializer.deserialize(decoder, value){{#if serializer.needsTypeAssertion}} as {{analysis.type.sourceText}}{{/if}};
        {{/if}}
        {{/if}}
        break;
      {{/each}}
      case DecodedElementIndex.UNKNOWN_NAME:
        TurboTransLogger.error(`Encounter unknown property \`${key}\` when deserialize \`{{class.className}}\`.`)
        throw new SerializationError(
          SerializationErrorCodes.ENCOUNTER_UNKNOWN_KEY,
          `Encounter unknown property \`${key}\` when deserialize \`{{class.className}}\`.`
        );
      case DecodedElementIndex.IGNORED_NAME:
        continue;
    }
  }

  {{! 必填属性验证 }}
  const missingProperties: string[] = [];
  {{#each properties}}
    {{#if analysis.isMust}}
      if (!{{analysis.name}}Seen) {
        missingProperties.push('{{formatPropertyName analysis}}');
      }
    {{/if}}
  {{/each}}

  if (missingProperties.length > 0) {
    TurboTransLogger.error(`Missing required properties [${missingProperties.map(item => `\`${item}\``).join(', ')}] when deserialize \`{{class.className}}\`.`)
    throw new SerializationError(
      SerializationErrorCodes.MISSING_REQUIRED_PROPERTY,
      `Missing required properties [${missingProperties.map(item => `\`${item}\``).join(', ')}] when deserialize \`{{class.className}}\`.`
    );
  }

  {{#if (isClassType class)}}
    {{! 解码构造函数属性（直接反序列化）}}
    {{! 构造函数参数（形参名和属性名一致）}}
    const result = new {{class.className}}{{#if class.generics.isGeneric}}<{{genericParametersString class.generics.parameters}}>{{/if}}(
      {{#each (getCtorProperties class.constructorParams properties)}}
      {{#unless analysis.decorators.isTransient}}
      {{analysis.name}}Value!{{#if serializer.needsTypeAssertion}} as {{analysis.type.sourceText}}{{/if}},
      {{/unless}}
      {{/each}});
  {{else}}
    const result: ESObject = {};
  {{/if}}

  {{! 可选属性赋值（构造函数外的属性）}}
  {{#each (postConstructorAssignments class.constructorParams properties)}}
  {{#unless analysis.decorators.isTransient}}
  if ({{analysis.name}}Seen) {
    {{#if (eq analysis.visibility "private")}}
    ObjectUtils.setProp(result, '{{analysis.name}}', {{analysis.name}}Value!{{#if serializer.needsTypeAssertion}} as {{analysis.type.sourceText}}{{/if}});
    {{else}}
    result.{{analysis.name}} = {{analysis.name}}Value!{{#if serializer.needsTypeAssertion}} as {{analysis.type.sourceText}}{{/if}};
    {{/if}}
  }
  {{/unless}}
  {{/each}}

  return result as {{class.className}}{{#if class.generics.isGeneric}}<{{genericParametersString class.generics.parameters}}>{{/if}};
}